package com.github.aloxc.plugin.restplus.navigator;

import com.github.aloxc.plugin.restplus.common.Consts;
import com.github.aloxc.plugin.restplus.component.TextPane;
import com.github.aloxc.plugin.restplus.component.VTree;
import com.github.aloxc.plugin.restplus.component.listener.VTreeMouseListener;
import com.github.aloxc.plugin.restplus.component.listener.VTreeShow;
import com.github.aloxc.plugin.restplus.entity.ConsoleContent;
import com.github.aloxc.plugin.restplus.entity.ConsoleStyle;
import com.github.aloxc.plugin.restplus.entity.Show;
import com.github.aloxc.plugin.restplus.entity.UserCase;
import com.github.aloxc.plugin.restplus.i18n.I18Bundle;
import com.github.aloxc.plugin.restplus.listener.*;
import com.github.aloxc.plugin.restplus.test.RestResponse;
import com.github.aloxc.plugin.restplus.test.TestResult;
import com.github.aloxc.plugin.restplus.utils.JsonUtils;
import com.github.aloxc.plugin.restplus.utils.StringUtils;
import com.intellij.openapi.editor.colors.FontPreferences;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
import com.intellij.ui.components.JBPanel;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.github.aloxc.plugin.restplus.common.Consts.BUTTON_DIMENSION;
import static com.github.aloxc.plugin.restplus.common.Consts.LINE_NUMBER_BACKGROUND_COLOR;
import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
import static javax.swing.tree.TreeSelectionModel.SINGLE_TREE_SELECTION;

/**
 * @author leero
 */
public class RestServiceDetail extends JBPanel {

    public JPanel urlPanel;
    public JButton sendButton;
    public JTabbedPane rightTabbedPane;
    private JTree userCaseTree;
    private JPanel requestPane;
    private JLabel caseTextPane;
    private JPanel midPane;
    private JButton saveCaseButton;
    private JPanel leftNavPane;
    private JButton testAllButton;
    private JScrollPane userCaseScroll;
    private JButton deleteButton;
    private JPanel rootPanel;
    private JPanel rightPane;
    private JPanel searchPane;
    private JCheckBox keyCheckBox;
    private JCheckBox valueCheckBox;
    private JTextField searchKey;
    private JButton searchButton;
    private JButton requestEnvButton;
    private JButton historyButton;
    private JPanel testPanel;
    private JScrollPane testResultPanel;

    private TextPane requestParamsTextArea;
    private TextPane requestTestTextArea;
    private TextPane requestBodyTextArea;
    private TextPane responseTextArea;
    private TextPane headerTextArea;
    private TextPane testResultTextPanel;
    private String url;
    private String method;
    private SendActionListener sendActionListener;
    private SaveAsActionListener saveAsActionListener;
    private VTree responseTree;
    private Project project;
    private JTree urlTree;
    private Module module;
    private VTreeShow vTreeShow;

    public RequestEnvironmentListener getRequestEnvironmentListener() {
        return requestEnvironmentListener;
    }

    private static String HEADERS = "Headers";
    private static String PARAMS = "Params";
    private static String BODYS = "RequestBody";
    private static String RESPONSE = "Response";
    private static String TEST = "Tests";
    private RequestEnvironmentListener requestEnvironmentListener;
    private CopyUrlActionListener copyUrlActionListener;
    private PushYapiActionListener pushYapiActionListener;
    private String parentName;
    private static ThreadLocal<SimpleDateFormat> SIMPLE_DATE_FORMAT = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("hh:mm:ss.SSS");
        }
    };

    /**
     * 获取拷贝url
     * @param component
     * @return
     */
    public CopyUrlActionListener getCopyUrlActionListener(JComponent component) {
        copyUrlActionListener.setComponent(component);
        return copyUrlActionListener;
    }

    /**
     * 推送接口到yapi
     * @param component
     * @return
     */
    public PushYapiActionListener getPushYapiActionListener(JComponent component) {
        pushYapiActionListener.setComponent(component);
        return pushYapiActionListener;
    }

    public static RestServiceDetail getInstance(Project p) {
        return p.getComponent(RestServiceDetail.class);
    }


    private RestServiceDetail() {
        super();
//        withEmptyText("JSON FORMAT");
        initComponent();
    }

    public SendActionListener getSendActionListener() {
        return sendActionListener;
    }

    public void initComponent() {
        initUi();
        responseTree = new VTree(LINE_NUMBER_BACKGROUND_COLOR);
        responseTree.setShowLineNumber(true);
        responseTree.setRowHeight(22);
        SimpleAttributeSet keyAttr = new SimpleAttributeSet();
        StyleConstants.setFontSize(keyAttr, 14);
        Font font = new Font(FontPreferences.DEFAULT_FONT_NAME, Font.PLAIN, 14);
        responseTree.setFont(font);
        vTreeShow = new VTreeShow(responseTree,getEffectiveFont());
        initActions();
        initTab();

    }

    public TextPane getRequestParamsTextArea() {
        return requestParamsTextArea;
    }

    private void initActions() {
        sendActionListener = new SendActionListener(this);
        saveAsActionListener = new SaveAsActionListener(this);
        requestEnvironmentListener = new RequestEnvironmentListener(this);
        copyUrlActionListener = new CopyUrlActionListener(this);
        pushYapiActionListener = new PushYapiActionListener(this);
        bindSendButtonActionListener();

        bindSearchActionListener();

        bindSearchKeyListener();

        bindSaveCaseListener();

        bindHistoryListener();

        bindUserCaseTreeListener();

        bindDeleteCaseListener();

        bindRequestEnvSettingListener();

        bindTestAllListener();

        bindResponseTreeListener();
    }

    private void bindResponseTreeListener() {
        responseTree.addMouseListener(new VTreeMouseListener(responseTree,vTreeShow.getJsonEleTreeMap()));
    }

    private void bindHistoryListener() {
        historyButton.addMouseListener(new HistoryMouseListener(this, false));
    }

    public String getParentName() {
        return parentName;
    }

    public String getUrl() {
        return url;
    }

    public Project getProject() {
        return project;
    }

    private void bindTestAllListener() {
        testAllButton.addActionListener(new TestAllListener(this));
    }

    public void setProject(Project project) {
        this.project = project;
    }

    public void setUrlTree(JTree myTree) {
        this.urlTree = myTree;
    }

    public JTree getUrlTree() {
        return this.urlTree;
    }

    public void setModule(Module module) {
        this.module = module;
    }

    public Module getModule() {
        return module;
    }

    public TextPane getRequestTestTextArea() {
        return requestTestTextArea;
    }

    public TextPane getRequestBodyTextArea() {
        return requestBodyTextArea;
    }

    public TextPane getResponseTextArea() {
        return responseTextArea;
    }

    public TextPane getHeaderTextArea() {
        return headerTextArea;
    }

    private void bindRequestEnvSettingListener() {
        requestEnvButton.addMouseListener(requestEnvironmentListener);
    }

    private void bindDeleteCaseListener() {
        deleteButton.addMouseListener(new DeleteUserCaseListener(this));
    }

    public void bindUserCaseTreeListener() {
        userCaseTree.addTreeSelectionListener(new UserCaseTreeListener(this));
        userCaseTree.addMouseListener(new UserCaseTreeListener(this));
    }

    private void bindSaveCaseListener() {
        saveCaseButton.addMouseListener(new SaveCaseListener(this));
    }

    public SaveAsActionListener getSaveAsActionListener() {
        return saveAsActionListener;
    }

    public JButton getSaveCaseButton() {
        return saveCaseButton;
    }

    /**
     * 搜索输入框按键 监听器
     */
    private void bindSearchKeyListener() {
        this.searchKey.addKeyListener(new SearchKeyListener(this));
    }

    public JTextField getSearchKey() {
        return searchKey;
    }

    /**
     * 搜索按钮动作监听
     */
    private void bindSearchActionListener() {
        this.searchButton.addActionListener(new SearchActionListener(this));
    }

    public void initTab() {
        this.headerTextArea = createTextArea("", false);
//        addRequestTabPanel("Headers", this.headerTextArea);

        this.requestParamsTextArea = createTextArea("", false);
//        addRequestTabPanel("Params", this.requestParamsTextArea);

        this.requestBodyTextArea = createTextArea("", false);
//        addRequestTabPanel("RequestBody", this.requestBodyTextArea);

        this.responseTextArea = createTextArea("", false);

        this.requestTestTextArea = createTextArea("", true);
//        addRequestTabPanel("Response", this.responseTextArea);

        this.rightTabbedPane.setVisible(false);

        responseTree.putClientProperty("Jtree.lineStyle", "Angled");
    }

    @Override
    protected void printComponent(Graphics g) {
        super.printComponent(g);
    }

    private void initUi() {
        GridLayoutManager rightLayoutManager = new GridLayoutManager(1, 3);
        rightLayoutManager.setHGap(1);
        rightLayoutManager.setVGap(1);
        requestPane = new JBPanel<>();
        requestPane.setLayout(rightLayoutManager);

        initRequestPanel();
        initUserCaseLeftPanel();
        initUserCaseMidPanel();
        initUserCaseRightPanel();
        initUserCasePanel();

        this.sendButton.setText(I18Bundle.getMessage("com.github.aloxc.plugin.restplus.request.send.text"));
        this.searchButton.setText(I18Bundle.getMessage("com.github.aloxc.plugin.restplus.response.search.text"));
        this.requestEnvButton.setToolTipText(I18Bundle.getMessage("com.github.aloxc.plugin.restplus.left.requestEnvButton.text"));
        this.saveCaseButton.setToolTipText(I18Bundle.getMessage("com.github.aloxc.plugin.restplus.left.saveCaseButton.text"));
        this.testAllButton.setToolTipText(I18Bundle.getMessage("com.github.aloxc.plugin.restplus.left.testAllButton.text"));
        this.deleteButton.setToolTipText(I18Bundle.getMessage("com.github.aloxc.plugin.restplus.left.deleteButton.text"));
        this.historyButton.setToolTipText(I18Bundle.getMessage("com.github.aloxc.plugin.restplus.left.historyButton.text"));
    }

    private void initUserCasePanel() {
        requestPane.add(leftNavPane,
                new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_SOUTHEAST, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_FIXED,
                        GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                        new Dimension(18, -1), new Dimension(18, -1), new Dimension(18, -1)));

        requestPane.add(midPane,
                new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_SOUTHEAST, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_FIXED,
                        GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                        new Dimension(200, -1), new Dimension(200, -1), new Dimension(200, -1)));

        requestPane.add(rightPane,
                new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_SOUTHEAST, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                        GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                        new Dimension(-1, -1), new Dimension(-1, -1), new Dimension(-1, -1)));

        this.add(requestPane,
                new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_SOUTHEAST, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                        GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                        new Dimension(-1, -1), new Dimension(-1, -1), new Dimension(-1, -1)));
    }

    private void initUserCaseRightPanel() {
        GridLayoutManager rightPaneLayoutManager = new GridLayoutManager(1, 1);
        rightPaneLayoutManager.setHGap(1);
        rightPaneLayoutManager.setVGap(1);
        rightPaneLayoutManager.setMargin(new Insets(0, 5, 0, 0));
        rightPane = new JBPanel<>();
        rightPane.setLayout(rightPaneLayoutManager);
        rightPane.add(rightTabbedPane,
                new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_SOUTHEAST, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                        GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                        new Dimension(-1, -1), new Dimension(-1, -1), new Dimension(-1, -1)));
    }

    public void findTreeChildValue(String findText){
        vTreeShow.findTreeChildValue(findText);
    }
    private void initUserCaseMidPanel() {
        int userCaseTreeWidth = 200;
        GridLayoutManager midPaneLayoutManager = new GridLayoutManager(2, 1);
        midPaneLayoutManager.setHGap(1);
        midPaneLayoutManager.setVGap(1);
        midPaneLayoutManager.setMargin(new Insets(0, 5, 0, 0));
        midPane = new JBPanel<>();
        midPane.setLayout(midPaneLayoutManager);
        midPane.setMaximumSize(new Dimension(userCaseTreeWidth, 26));
        midPane.setMinimumSize(new Dimension(userCaseTreeWidth, 26));
        midPane.setPreferredSize(new Dimension(userCaseTreeWidth, 26));

        midPane.add(caseTextPane,
                new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_SOUTHEAST, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED,
                        new Dimension(userCaseTreeWidth, 28), new Dimension(userCaseTreeWidth, 28), new Dimension(userCaseTreeWidth, 28)));


        userCaseTree.setBackground(rightTabbedPane.getBackground());

        DefaultTreeModel model = (DefaultTreeModel) userCaseTree.getModel();
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
        root.removeAllChildren();

        model.reload(root);
        userCaseTree.expandPath(new TreePath(root));
        userCaseTree.updateUI();
        //不显示根节点
        userCaseTree.setRootVisible(false);
        userCaseTree.setShowsRootHandles(false);
        userCaseTree.setRowHeight(22);
        DefaultTreeSelectionModel singleSelectionModel = new DefaultTreeSelectionModel();
        singleSelectionModel.setSelectionMode(SINGLE_TREE_SELECTION);
        userCaseTree.setSelectionModel(singleSelectionModel);
        DefaultTreeCellRenderer render = (DefaultTreeCellRenderer) (userCaseTree.getCellRenderer());
        render.setIcon(null);
        render.setLeafIcon(null);
        render.setOpenIcon(null);
        render.setClosedIcon(null);


        ScrollPaneLayout userCaseScrollLayoutManager = new ScrollPaneLayout();
        userCaseScrollLayoutManager.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);
        userCaseScrollLayoutManager.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_AS_NEEDED);
        userCaseScroll.setLayout(userCaseScrollLayoutManager);

        userCaseScroll.getViewport().add(userCaseTree,
                new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_SOUTHEAST, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_FIXED,
                        GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                        new Dimension(userCaseTreeWidth, -1), new Dimension(userCaseTreeWidth, -1), new Dimension(userCaseTreeWidth, -1)));
        midPane.add(userCaseScroll,
                new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_SOUTHEAST, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_FIXED,
                        GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                        new Dimension(userCaseTreeWidth, -1), new Dimension(userCaseTreeWidth, -1), new Dimension(userCaseTreeWidth, -1)));

    }

    private void initUserCaseLeftPanel() {
        LayoutManager flowLayoutManager = new FlowLayout();
        leftNavPane = new JBPanel<>();
        leftNavPane.setLayout(flowLayoutManager);
        saveCaseButton.setBorder(BorderFactory.createRaisedBevelBorder());
        saveCaseButton.setBorderPainted(false);
        saveCaseButton.setOpaque(false);
        saveCaseButton.setRolloverEnabled(true);
        saveCaseButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));

        testAllButton.setBorder(BorderFactory.createRaisedBevelBorder());
        testAllButton.setBorderPainted(false);
        testAllButton.setOpaque(false);
        testAllButton.setRolloverEnabled(true);
        testAllButton.setFocusPainted(true);
        testAllButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));


        deleteButton.setBorder(BorderFactory.createRaisedBevelBorder());
        deleteButton.setBorderPainted(false);
        deleteButton.setOpaque(false);
        deleteButton.setRolloverEnabled(true);
        deleteButton.setFocusPainted(true);
        deleteButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));

        historyButton.setBorder(BorderFactory.createRaisedBevelBorder());
        historyButton.setBorderPainted(false);
        historyButton.setOpaque(false);
        historyButton.setRolloverEnabled(true);
        historyButton.setFocusPainted(true);
        historyButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));

        requestEnvButton.setBorder(BorderFactory.createRaisedBevelBorder());
        requestEnvButton.setBorderPainted(false);
        requestEnvButton.setOpaque(false);
        requestEnvButton.setRolloverEnabled(true);
        requestEnvButton.setFocusPainted(true);
        requestEnvButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));

        leftNavPane.add(requestEnvButton,
                new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_SOUTHEAST, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED,
                        BUTTON_DIMENSION, BUTTON_DIMENSION, BUTTON_DIMENSION));
        leftNavPane.add(saveCaseButton,
                new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_SOUTHEAST, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED,
                        BUTTON_DIMENSION, BUTTON_DIMENSION, BUTTON_DIMENSION));

        leftNavPane.add(testAllButton,
                new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_SOUTHEAST, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED,
                        BUTTON_DIMENSION, BUTTON_DIMENSION, BUTTON_DIMENSION));

        leftNavPane.add(deleteButton,
                new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_SOUTHEAST, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED,
                        BUTTON_DIMENSION, BUTTON_DIMENSION, BUTTON_DIMENSION));
        leftNavPane.add(historyButton,
                new GridConstraints(4, 0, 1, 1, GridConstraints.ANCHOR_SOUTHEAST, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED,
                        BUTTON_DIMENSION, BUTTON_DIMENSION, BUTTON_DIMENSION));

    }

    private void initRequestPanel() {
        searchKey.setAutoscrolls(true);
        urlPanel = new JBPanel();
        GridLayoutManager mgr = new GridLayoutManager(1, 3);
        mgr.setHGap(5);
        mgr.setVGap(1);
        mgr.setMargin(new Insets(0, 5, 0, 5));
        urlPanel.setLayout(mgr);

        sendButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        urlPanel.add(sendButton,
                new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_SOUTHEAST, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED,
                        null, null, null));
        urlPanel.add(searchKey,
                new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_SOUTHEAST, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                        GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
                        null, null, null));

        searchButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        urlPanel.add(searchButton,
                new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_SOUTHEAST, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED,
                        null, null, null));
        this.setBorder(BorderFactory.createEmptyBorder());
        this.setLayout(new GridLayoutManager(2, 1));
        this.add(urlPanel,
                new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
                        GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED,
                        null, null, null));
    }

    public String getMethod() {
        return method;
    }

    public void consoleTest(RestResponse response) {
        if (response.getTestResultList().size() > 0) {
            response.getTestResultList().stream().forEach(r -> {
                ConsoleContent[] contents = new ConsoleContent[3];
                ConsoleContent content = new ConsoleContent();
                content.setContent(I18Bundle.getMessage("com.github.aloxc.plugin.restplus.test.result.testcase.text"));
                content.setConsoleStyle(ConsoleStyle.NORMAL);
                contents[0] = content;
                content = new ConsoleContent();
                content.setContent(r.getName());
                content.setConsoleStyle(ConsoleStyle.MAIN);
                contents[1] = content;

                if (r.isSuccess()) {
                    content = new ConsoleContent();
                    content.setContent(I18Bundle.getMessage("com.github.aloxc.plugin.restplus.test.result.passed.text"));
                    content.setConsoleStyle(ConsoleStyle.GREEN);
                    contents[2] = content;
                } else {
                    content = new ConsoleContent();
                    content.setContent(String.format(I18Bundle.getMessage("com.github.aloxc.plugin.restplus.test.result.failed.text"), r.getMessage()));
                    content.setConsoleStyle(ConsoleStyle.RED);
                    contents[2] = content;
                }
                addContent(contents);
            });
            if (response.getPrintList().size() > 0) {
                response.getPrintList().stream().forEach(it -> {
                    addContent(it.toString());
//                    addContent(JsonUtils.toJson(it,true));
                });
            }
        }
    }

    public Map<String, List<TreePath>> getSearchMap() {
        return vTreeShow.getSearchMap();
    }

    public void setSearchIndex(int searchIndex) {
        this.vTreeShow.setSearchIndex(searchIndex);
    }

    public int getSearchIndex() {
        return vTreeShow.getSearchIndex();
    }

    public void setTestIcon(RestResponse response) {
        int index = 0;
        for (int i = 0; i < rightTabbedPane.getTabCount(); i++) {
            if (rightTabbedPane.getTitleAt(i).equals(TEST)) {
                index = i;
                break;
            }
        }
        if (response.getTestResultList().size() > 0) {
            int successCount = (int) response.getTestResultList().stream().filter(TestResult::isSuccess).count();
            int failCount = response.getTestResultList().size() - successCount;
            String tips = String.format(I18Bundle.getMessage("com.github.aloxc.plugin.restplus.test.tips.text"), successCount, failCount);
            rightTabbedPane.setToolTipTextAt(index, tips);
            if (failCount == 0) {
                rightTabbedPane.setIconAt(index, Consts.Icons.YES);
            } else {
                if (failCount == response.getTestResultList().size()) {
                    rightTabbedPane.setIconAt(index, Consts.Icons.NO);
                } else {
                    rightTabbedPane.setIconAt(index, Consts.Icons.HALF);
                }
            }
        } else {
            rightTabbedPane.setIconAt(index, null);
        }
    }

    public void setTestIcon(int allCount, int successCount, int failCount) {
        int index = 0;
        for (int i = 0; i < rightTabbedPane.getTabCount(); i++) {
            if (rightTabbedPane.getTitleAt(i).equals(TEST)) {
                index = i;
                rightTabbedPane.setSelectedComponent(rightTabbedPane.getComponentAt(i));
                break;
            }
        }
        if (allCount > 0) {
            String tips = String.format(I18Bundle.getMessage("com.github.aloxc.plugin.restplus.test.tips.text"), successCount, failCount);
            rightTabbedPane.setToolTipTextAt(index, tips);
            if (failCount == 0) {
                rightTabbedPane.setIconAt(index, Consts.Icons.YES);
            } else {
                if (failCount == allCount) {
                    rightTabbedPane.setIconAt(index, Consts.Icons.NO);
                } else {
                    rightTabbedPane.setIconAt(index, Consts.Icons.HALF);
                }
            }
            ConsoleContent[] contents = new ConsoleContent[5];
            ConsoleContent content = new ConsoleContent();
            content.setContent(I18Bundle.getMessage("com.github.aloxc.plugin.restplus.test.result.testcase.text"));
            content.setConsoleStyle(ConsoleStyle.NORMAL);
            contents[0] = content;

            content = new ConsoleContent();
            content.setContent(String.valueOf(allCount));
            content.setConsoleStyle(ConsoleStyle.MAIN);
            contents[1] = content;

            content = new ConsoleContent();
            content.setContent(I18Bundle.getMessage("com.github.aloxc.plugin.restplus.test.result.passed.text"));
            content.setConsoleStyle(ConsoleStyle.NORMAL);
            contents[2] = content;

            content = new ConsoleContent();
            content.setContent(String.valueOf(successCount));
            content.setConsoleStyle(ConsoleStyle.GREEN);
            contents[3] = content;

            content = new ConsoleContent();
            content.setContent(String.format(I18Bundle.getMessage("com.github.aloxc.plugin.restplus.test.result.failed.text"), String.valueOf(failCount)));
            content.setConsoleStyle(ConsoleStyle.RED);
            contents[4] = content;

            addContent(contents);
        } else {
            rightTabbedPane.setIconAt(index, null);
        }
    }

    private void bindSendButtonActionListener() {
        sendButton.addActionListener(sendActionListener);
    }

    public void removeResponseTab() {
        int tabCount = rightTabbedPane.getTabCount();
        Component componentAt = null;
        for (int i = 0; i < tabCount; i++) {
            if (rightTabbedPane.getTitleAt(i).equals(RESPONSE)) {
                componentAt = rightTabbedPane.getComponentAt(i);
                rightTabbedPane.remove(componentAt);
                break;
            }
        }
    }

    public void addRequestHeaderTab(Map<String, Object> headers) {
        if (headers == null) {
            headers = new HashMap(2 << 3);
        }
        this.headerTextArea.setText(JsonUtils.toJson(headers, true));
        addRequestTabPanel(HEADERS, this.headerTextArea, true, null);
    }

    public void addRequestParamsTab(Map<String, Object> requestParams) {
        if (requestParams == null) {
            requestParams = new HashMap(2 << 3);
        }
        this.requestParamsTextArea.setText(JsonUtils.toJson(requestParams, true));
        addRequestTabPanel(PARAMS, this.requestParamsTextArea, true, null);
    }

    public void addRequestTestTab(String script) {
        if (StringUtils.isNullOrEmpty(script)) {
            script = "";
        }
        this.requestTestTextArea.setText(script);
//        addRequestTabPanel(TEST, this.requestTestTextArea,false,null);

        int tabCount = rightTabbedPane.getTabCount();
        Component componentAt = null;
        for (int i = 0; i < tabCount; i++) {
            if (rightTabbedPane.getTitleAt(i).equals(TEST)) {
                componentAt = rightTabbedPane.getComponentAt(i);
//                rightTabbedPane.addTab(title,icon, componentAt);
                rightTabbedPane.setSelectedComponent(componentAt);
                break;
            }
        }
        if (componentAt == null) {
            GridLayoutManager testLayout = new GridLayoutManager(2, 1);
            testLayout.setHGap(1);
            testLayout.setVGap(1);

            this.testPanel = new JBPanel<>();


            this.testPanel.setLayout(testLayout);

            this.testResultTextPanel = new TextPane(LINE_NUMBER_BACKGROUND_COLOR,project);
            this.testResultTextPanel.setShowLineNumber(true);
            this.testResultTextPanel.setFont(getEffectiveFont());
//            this.testResultTextPanel.setShowLineNumber(true);
            Dimension testResultDimension = new Dimension(-1, 150);
            Dimension testDimension = new Dimension(-1, 14000);
            testResultTextPanel.setMinimumSize(testResultDimension);
            testResultTextPanel.setMaximumSize(testResultDimension);
            testResultTextPanel.setPreferredSize(testResultDimension);
            requestTestTextArea.setMinimumSize(testDimension);
            requestTestTextArea.setMaximumSize(testDimension);
            requestTestTextArea.setPreferredSize(testDimension);
//            testResultTextPanel.setEnabled(false);

//            testResultTextPanel.addKeyListener(new TestResultMouseListener(testResultTextPanel));
            requestTestTextArea.addKeyListener(new TextPaneKeyAdapter(requestTestTextArea,true));

            this.testResultPanel = new JScrollPane(this.testResultTextPanel, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
            //设置滚动条的滚动速度
            testResultPanel.getVerticalScrollBar().setUnitIncrement(15);
            //解决闪烁问题
            testResultPanel.getVerticalScrollBar().setDoubleBuffered(true);
            testResultTextPanel.setEditable(false);
            testResultTextPanel.addMouseListener(new TestResultMouseListener());
            //设置字体大小制
            Style normal = testResultTextPanel.getStyledDocument().addStyle(null, null);
            StyleConstants.setFontFamily(normal, "Monospaced");
            StyleConstants.setFontSize(normal, 14);

            Style normalStyle = testResultTextPanel.addStyle("normal", normal);
            Style redStyle = testResultTextPanel.addStyle("red", normal);
            Style mainStyle = testResultTextPanel.addStyle("main", normal);
            Style greenStyle = testResultTextPanel.addStyle("green", normal);

            StyleConstants.setForeground(redStyle, Color.RED);
            StyleConstants.setForeground(mainStyle, Consts.MAIN_COLOR);
            StyleConstants.setForeground(greenStyle, Color.GREEN);

            JScrollPane jbScrollPane = new JScrollPane(this.requestTestTextArea, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
            testPanel.add(jbScrollPane,
                    new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_NORTHWEST, GridConstraints.FILL_BOTH,
                            GridConstraints.FILL_BOTH,
                            GridConstraints.FILL_BOTH,
                            null, null, null));
            testPanel.add(testResultPanel,
                    new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_SOUTH, GridConstraints.FILL_BOTH,
                            GridConstraints.FILL_HORIZONTAL,
                            GridConstraints.FILL_VERTICAL,
                            testResultDimension, testResultDimension, testResultDimension));
            rightTabbedPane.addTab(TEST, null, testPanel);
            rightTabbedPane.setSelectedComponent(testPanel);
        }
        this.rightTabbedPane.setVisible(true);
    }

    public void addContent(String content, Exception e) {
        SimpleAttributeSet attrset = new SimpleAttributeSet();
        StyleConstants.setFontSize(attrset, 14);
        //获得文本对象
        Document docs = testResultTextPanel.getDocument();
        try {
            StringWriter stringWriter = new StringWriter();
            PrintWriter printWriter = new PrintWriter(stringWriter);
            e.printStackTrace(printWriter);
            //对文本进行追加
            docs.insertString(docs.getLength(), " " + SIMPLE_DATE_FORMAT.get().format(new Date()) + "\t" + content + "\n" + stringWriter.toString(), attrset);
        } catch (BadLocationException ex) {
            ex.printStackTrace();
        }
    }

    public void addContent(String content, Throwable e) {
        SimpleAttributeSet attrset = new SimpleAttributeSet();
        StyleConstants.setFontSize(attrset, 14);
        //获得文本对象
        Document docs = testResultTextPanel.getDocument();
        try {
            StringWriter stringWriter = new StringWriter();
            PrintWriter printWriter = new PrintWriter(stringWriter);
            e.printStackTrace(printWriter);
            //对文本进行追加
            docs.insertString(docs.getLength(), " " + SIMPLE_DATE_FORMAT.get().format(new Date()) + "\t" + content + "\n" + stringWriter.toString(), attrset);
        } catch (BadLocationException ex) {
            ex.printStackTrace();
        }
    }

    public void addContent(ConsoleContent content) {
        //获得文本对象
        Document docs = testResultTextPanel.getDocument();
        try {
            //对文本进行追加
            docs.insertString(docs.getLength(), " " + SIMPLE_DATE_FORMAT.get().format(new Date()), testResultTextPanel.getStyle("main"));
            //对文本进行追加
            docs.insertString(docs.getLength(), " " + content.getContent() + "\n", testResultTextPanel.getStyle(content.getConsoleStyle().name().toLowerCase()));
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
        testResultTextPanel.setCaretPosition(docs.getLength());
    }

    public void addContent(ConsoleContent... contents) {
        //获得文本对象
        Document docs = testResultTextPanel.getDocument();
//        testResultTextPanel.setContentType("text/plain");
        try {
            //对文本进行追加
            docs.insertString(docs.getLength(), " " + SIMPLE_DATE_FORMAT.get().format(new Date()), testResultTextPanel.getStyle("main"));
            //对文本进行追加
            for (ConsoleContent content : contents) {
                docs.insertString(docs.getLength(), " " + content.getContent(), testResultTextPanel.getStyle(content.getConsoleStyle().name().toLowerCase()));
            }
            docs.insertString(docs.getLength(), " \n", testResultTextPanel.getStyle("normal"));
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
        testResultTextPanel.setCaretPosition(docs.getLength());
    }

    public void addContent(String content) {
        //获得文本对象
        Document docs = testResultTextPanel.getDocument();
        try {
            //对文本进行追加
            docs.insertString(docs.getLength(), " " + SIMPLE_DATE_FORMAT.get().format(new Date()), testResultTextPanel.getStyle("main"));
            //对文本进行追加
            docs.insertString(docs.getLength(), " " + content + "\n", testResultTextPanel.getStyle("normal"));
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
        testResultTextPanel.setCaretPosition(docs.getLength());
    }

    public void addRequestBodyTabPanel(String text) {
        if (StringUtils.isNotBlank(text)) {
            this.requestBodyTextArea.setText(text);
            addRequestTabPanel(BODYS, this.requestBodyTextArea, true, null);
        }
    }

    public void addRequestTabPanel(String title, TextPane jTextArea, boolean format, Icon icon) {
        int tabCount = rightTabbedPane.getTabCount();
        Component componentAt = null;
        for (int i = 0; i < tabCount; i++) {
            if (rightTabbedPane.getTitleAt(i).equals(title)) {
                componentAt = rightTabbedPane.getComponentAt(i);
                rightTabbedPane.setSelectedComponent(componentAt);
                break;
            }
        }
        if (componentAt == null) {
            JScrollPane jbScrollPane = new JBScrollPane(jTextArea, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
            jTextArea.addKeyListener(new TextPaneKeyAdapter(jTextArea,false));
            rightTabbedPane.addTab(title, icon, jbScrollPane);
            rightTabbedPane.setSelectedComponent(jbScrollPane);
        }
        this.rightTabbedPane.setVisible(true);
        if (format) {
            jTextArea.format();
        }
    }

    public void addResponseTreeTabPanel() {
        int tabCount = rightTabbedPane.getTabCount();
        Component componentAt = null;
        for (int i = 0; i < tabCount; i++) {
            if (rightTabbedPane.getTitleAt(i).equals(RESPONSE)) {
                componentAt = rightTabbedPane.getComponentAt(i);
                rightTabbedPane.addTab(RESPONSE, componentAt);
                rightTabbedPane.setSelectedComponent(componentAt);
                break;
            }
        }
        if (componentAt == null) {
            JScrollPane jbScrollPane = new JBScrollPane(responseTree, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
            rightTabbedPane.addTab(RESPONSE, jbScrollPane);
            rightTabbedPane.setSelectedComponent(jbScrollPane);
        }
        this.rightTabbedPane.setVisible(true);
    }

    /**
     * 添加 Response Tab
     */
    public void addResponseTabPanel(RestResponse response) {
        Show show = Show.get();
        if (show == Show.CODE) {
            responseTextArea.setVisible(true);
            responseTree.setVisible(false);

            responseTextArea.setText(response.getContent());
            responseTextArea.format();
            addRequestTabPanel(RESPONSE, responseTextArea, true, Consts.Icons.Code.ERROR);
        } else {
            responseTextArea.setVisible(false);
            responseTree.setVisible(true);

            vTreeShow.showInTree(response.getContent());
            addResponseTreeTabPanel();
        }
        int index = 0;
        for (int i = 0; i < rightTabbedPane.getTabCount(); i++) {
            if (rightTabbedPane.getTitleAt(i).equals(RESPONSE)) {
                index = i;
                break;
            }
        }
        if (response.getStatusCode() == 200) {
            rightTabbedPane.setIconAt(index, null);
        } else {
            rightTabbedPane.setIconAt(index, IconLoader.getIcon("/icons/code/" + response.getStatusCode() + ".png"));
        }
    }

    public JTree getUserCaseTree() {
        return userCaseTree;
    }

    public JButton getSendButton() {
        return sendButton;
    }

    @NotNull
    public TextPane createTextArea(String text, boolean javaScript) {
        Font font = getEffectiveFont();
        TextPane textArea = new TextPane(LINE_NUMBER_BACKGROUND_COLOR,project);
        textArea.setShowLineNumber(true);
        textArea.setText(text);
        textArea.setFont(font);
        textArea.setJavascript(javaScript);
        if(javaScript) {
            textArea.setToolTipText(I18Bundle.getMessage("com.github.aloxc.plugin.restplus.textpane.testtooltips.text"));
        } else {
            textArea.setToolTipText(I18Bundle.getMessage("com.github.aloxc.plugin.restplus.textpane.tooltips.text"));
        }
        textArea.format();
        textArea.addMouseListener(new TextPaneKeyAdapter(textArea,javaScript));

        textArea.addKeyListener(new KeyAdapter() {
            @Override
            public void keyTyped(KeyEvent e) {
                String text = textArea.getText();
                getEffectiveFont(text);
            }
        });

        textArea.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() > 1) {
                    //CopyPasteManager.getInstance().setContents(new StringSelection(textArea.getText()));
                }
            }
        });
        return textArea;
    }

    @NotNull
    private Font getEffectiveFont(String text) {
//        FontPreferences fontPreferences = this.getFontPreferences();
//        List<String> effectiveFontFamilies = fontPreferences.getEffectiveFontFamilies();
//        int size = fontPreferences.getSize(fontPreferences.getFontFamily());
//        Font font = new Font(FontPreferences.DEFAULT_FONT_NAME, Font.PLAIN, size);
//        for (String effectiveFontFamily : effectiveFontFamilies) {
//            Font effectiveFont = new Font(effectiveFontFamily, Font.PLAIN, size);
//            if (effectiveFont.canDisplayUpTo(text) == -1) {
//                font = effectiveFont;
//                break;
//            }
//        }
//        return font;
        return getEffectiveFont();
    }

    @NotNull
    private final FontPreferences getFontPreferences() {
        return new FontPreferences();
    }

    @NotNull
    private Font getEffectiveFont() {
        int size = 14;
        return new Font("Monospaced", Font.PLAIN, size);
    }


    public void resetRequestTabbedPane() {
        this.rightTabbedPane.setVisible(false);
        this.rightTabbedPane.removeAll();
        resetTextComponent(requestParamsTextArea);
        resetTextComponent(requestBodyTextArea);
        resetTextComponent(responseTextArea);

    }

    private void resetTextComponent(TextPane textComponent) {
        textComponent.setText("");
    }

    public void setMethod(String method) {
        if (this.requestBodyTextArea != null) {
            this.requestBodyTextArea.setText("");
        }
        this.method = method;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    /**
     * 设置左导航的用例列表
     *
     * @param parentName
     * @param method 请求的方法（GET\POST\....）
     */
    public void setUserCase(String parentName,final String method) {
        this.parentName = parentName;
        DefaultTreeModel model = (DefaultTreeModel) userCaseTree.getModel();
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
        root.removeAllChildren();


        Map<String, UserCase> userCaseMap = project.getComponent(
                RestServicesNavigator.class)
                .getConfig().getUserCaseMap().get(
                        (parentName != null ? parentName + ":" : "")
                                + url
                );
        if (userCaseMap != null) {
            userCaseMap.keySet().stream().sorted().forEach(k -> {
                String name = UserCase.getUserCaseName(k);
                String m = UserCase.getUserCaseMethod(k);
                if(m.equals(method)) {
                    DefaultMutableTreeNode node = new DefaultMutableTreeNode(name);
                    root.add(node);
                }
            });
        }
        model.reload(root);
        userCaseTree.expandPath(new TreePath(root));
        userCaseTree.updateUI();
        DefaultTreeCellRenderer render = (DefaultTreeCellRenderer) (userCaseTree.getCellRenderer());
        render.setIcon(null);
        render.setLeafIcon(null);
        render.setOpenIcon(null);
        render.setClosedIcon(null);
    }


}